home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / adnmod02 / modunit.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1995-03-22  |  42.1 KB  |  1,294 lines

  1. {AdnMod 0.2 by Beta/Adrenalin.
  2.  GUS only
  3.  Thanks to:
  4.     flap / Capacala for sending me "some" info
  5.     Mark Feldham for PCGPE
  6.     Mark Dixon for his GUS669 source
  7.     Thunder for excellent info about MODs
  8.     Tran & Joshua C. Jensen for releasing ultradox
  9.  
  10.  Greets:
  11.     Wihannes / Nordic vision
  12.     Solar / Hysteria
  13.     Psyko / Acidface software
  14.     TOP4.ZIP
  15.     All users of Metropoli & Starport
  16. }
  17. unit modunit;
  18. interface
  19. uses dos;
  20.  
  21. const
  22. maxchn = 8;   {max # of channels in mod. Lower this, if you run out
  23.                of memory}
  24. amp_vol : byte = 14;  {amplifying volume. Increasing by one doubles
  25.                        the volume}
  26.  
  27. def_pan : byte = 4;        {default panning. 0-7}
  28.  
  29. max_per = 1000;          {Max & min period for Amiga limits}
  30. min_per = 20;            {not implemented anymore coz of extra octaves}
  31. Base : word = $200;       {GUS address}
  32.  
  33. mod_error : word = 0;
  34. {0 = no error
  35.  1 = wrong number of channels
  36.  2 = load error
  37.  3 = out of pattern memory
  38.  255 = other error}
  39.  
  40. per_table : array[0..15,1..48 ] of word = (
  41.    (856,808,762,720,678,640,604,570,538,508,480,453,
  42.    428,404,381,360,339,320,302,285,269,254,240,226,
  43.    214,202,190,180,170,160,151,143,135,127,120,113,
  44.    107,101,95,90,85,80,75,71,67,63,60,56),
  45.  
  46. (850,802,757,715,674,637,601,567,535,505,477,450,{ : C-1 to B-1 Finetune +1}
  47. 425,401,379,357,337,318,300,284,268,253,239,225, { : C-2 to B-2 Finetune +1}
  48. 213,201,189,179,169,159,150,142,134,126,119,113, { : C-3 to B-3 Finetune +1}
  49. 106,100,94,89,84,79,75,71,67,83,59,56),          { : C-4 to B-4 Finetune +1}
  50.  
  51.  
  52. (844,796,752,709,670,632,597,563,532,502,474,447,{ : C-1 to B-1 Finetune +2}
  53. 422,398,376,355,335,316,298,282,266,251,237,224, { : C-2 to B-2 Finetune +2}
  54. 211,199,188,177,167,158,149,141,133,125,118,112, { : C-3 to B-3 Finetune +2}
  55. 105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59, 56),{ : C-4 to B-4 Finetune +2}
  56.  
  57. (838,791,746,704,665,628,592,559,528,498,470,444,{ : C-1 to B-1 Finetune +3}
  58. 419,395,373,352,332,314,296,280,264,249,235,222, { : C-2 to B-2 Finetune +3}
  59. 209,198,187,176,166,157,148,140,132,125,118,111, { : C-3 to B-3 Finetune +3}
  60. 104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59, 55),{ : C-4 to B-4 Finetune +3}
  61.  
  62. (832,785,741,699,660,623,588,555,524,495,467,441,{ : C-1 to B-1 Finetune +4}
  63. 416,392,370,350,330,312,294,278,262,247,233,220, { : C-2 to B-2 Finetune +4}
  64. 208,196,185,175,165,156,147,139,131,124,117,110, { : C-3 to B-3 Finetune +4}
  65. 104, 98, 92, 87, 82, 78, 73, 69, 65, 62, 58, 55), {; C-4 to B-4 Finetune +4}
  66.  
  67. (826,779,736,694,655,619,584,551,520,491,463,437,{ : C-1 to B-1 Finetune +5}
  68. 413,390,368,347,328,309,292,276,260,245,232,219, { : C-2 to B-2 Finetune +5}
  69. 206,195,184,174,164,155,146,138,130,123,116,109, { : C-3 to B-3 Finetune +5}
  70. 103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58, 54),{ ; C-4 to B-4 Finetune +5}
  71.  
  72. (820,774,730,689,651,614,580,547,516,487,460,434,{ : C-1 to B-1 Finetune +6}
  73. 410,387,365,345,325,307,290,274,258,244,230,217, { : C-2 to B-2 Finetune +6}
  74. 205,193,183,172,163,154,145,137,129,122,115,109, { : C-3 to B-3 Finetune +6}
  75. 102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57, 54),{ : C-4 to B-4 Finetune +6}
  76.  
  77. (814,768,725,684,646,610,575,543,513,484,457,431,{ : C-1 to B-1 Finetune +7}
  78. 407,384,363,342,323,305,288,272,256,242,228,216, { : C-2 to B-2 Finetune +7}
  79. 204,192,181,171,161,152,144,136,128,121,114,108, { : C-3 to B-3 Finetune +7}
  80. 102, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54),{ : C-4 to B-4 Finetune +7}
  81.  
  82. (907,856,808,762,720,678,640,604,570,538,504,480,{ : C-1 to B-1 Finetune -8 }
  83. 453,428,404,381,360,339,320,302,285,269,254,240, { : C-2 to B-2 Finetune -8  }
  84. 226,214,202,190,180,170,160,151,143,135,127,120, { : C-3 to B-3 Finetune -8 }
  85. 113,107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60),{ : C-4 to B-4 Finetune -8}
  86.  
  87.  
  88. (900,850,802,757,715,675,636,601,567,535,505,477,{ : C-1 to B-1 Finetune -7 }
  89. 450,425,401,379,357,337,318,300,284,268,253,238, { : C-2 to B-2 Finetune -7  }
  90. 225,212,200,189,179,169,159,150,142,134,126,119, { : C-3 to B-3 Finetune -7 }
  91. 112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59),{ : C-4 to B-4 Finetune -7}
  92.  
  93. (894,844,796,752,709,670,632,597,563,532,502,474,{ : C-1 to B-1 Finetune -6 }
  94. 447,422,398,376,355,335,316,298,282,266,251,237, { : C-2 to B-2 Finetune -6  }
  95. 223,211,199,188,177,167,158,149,141,133,125,118, { : C-3 to B-3 Finetune -6 }
  96. 111,105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59),{ : C-4 to B-4 Finetune -6}
  97.  
  98. (887,838,791,746,704,665,628,592,559,528,498,470,{ : C-1 to B-1 Finetune -5 }
  99. 444,419,395,373,352,332,314,296,280,264,249,235, { : C-2 to B-2 Finetune -5  }
  100. 222,209,198,187,176,166,157,148,140,132,125,118, { : C-3 to B-3 Finetune -5  }
  101. 111,104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59),{ : C-4 to B-4 Finetune -5}
  102.  
  103. (881,832,785,741,699,660,623,588,555,524,494,467,{ : C-1 to B-1 Finetune -4 }
  104. 441,416,392,370,350,330,312,294,278,262,247,233, { : C-2 to B-2 Finetune -4  }
  105. 220,208,196,185,175,165,156,147,139,131,123,117, { : C-3 to B-3 Finetune -4 }
  106. 110,104, 98, 92, 87, 82, 78, 73, 69, 65, 61, 58),{   C-4 to H-4 Finetune -4}
  107.  
  108. (875,826,779,736,694,655,619,584,551,520,491,463,{ : C-1 to B-1 Finetune -3 }
  109. 437,413,390,368,347,338,309,292,276,260,245,232, { : C-2 to B-2 Finetune -3  }
  110. 219,206,195,184,174,164,155,146,138,130,123,116, { : C-3 to B-3 Finetune -3 }
  111. 109,103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58),{   C-4 to H-4 Finetune -3}
  112.  
  113. (868,820,774,730,689,651,614,580,547,516,487,460,{ : C-1 to B-1 Finetune -2 }
  114. 434,410,387,365,345,325,307,290,274,258,244,230, { : C-2 to B-2 Finetune -2  }
  115. 217,205,193,183,172,163,154,145,137,129,122,115, { : C-3 to B-3 Finetune -2 }
  116. 108,102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57),{   C-4 to H-4 Finetune -2}
  117.  
  118. (862,814,768,725,684,646,610,575,543,513,484,457,{ : C-1 to B-1 Finetune -1 }
  119. 431,407,384,363,342,323,305,288,272,256,242,228, { : C-2 to B-2 Finetune -1  }
  120. 216,203,192,181,171,161,152,144,136,128,121,114, { : C-3 to B-3 Finetune -1}
  121. 108,101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57));{  C-4 to H-4 Finetune -1}
  122.  
  123. gusvol : array[0..64] of word =     {volume table}
  124.  
  125.   (0,1750,2503,2701,2741,2781,2944,2964,2981,
  126.   3000,3017,3034,3052,3070,3207,3215,3224,
  127.  
  128.   3232,3240,3248,3256,3263,3271,3279,3287,
  129.   3294,3303,3310,3317,3325,3458,3462,3466,
  130.  
  131.   3469,3473,3478,3481,3484,3489,3492,3495,
  132.   3499,3502,3506,3509,3513,3517,3520,3524,
  133.  
  134.   3528,3532,3534,3538,3543,3545,3549,3552,
  135.   3556,3558,3563,3565,3570,3573,3577,3580);
  136.  
  137. vib_tbl : array[0..2,0..63] of shortint =
  138. ((0,6,12,19,24,30,36,41,45,49,53,56,59,61,63,64,
  139. 64,64,63,61,59,56,53,49,45,41,36,30,24,19,12,6,
  140. 0,-6,-12,-19,-24,-30,-36,-41,-45,-49,-53,-56,-59,-61,-63,-64,
  141. -64,-64,-63,-61,-59,-56,-53,-49,-45,-41,-36,-30,-24,-19,-12,-6),
  142. (-63,-61,-59,-57,-55,-53,-51,-49,-47,-45,-43,-41,-39,-37,-35,-33,
  143. -31,-29,-27,-25,-23,-21,-19,-17,-15,-13,-11,-9,-7,-5,-3,-1,
  144. 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,
  145. 33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63),
  146. (-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,
  147. -64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,
  148. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  149. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64));
  150.  
  151.  
  152. type
  153.   t_memarray = array[0..2000] of word;
  154.   t_channel = record
  155.                 Vol : byte;       {current volume 0-64}
  156.                 note : byte;      {current note 1(C-1) to 48(B-4)}
  157.                 Per,dper : word;  {period & dest. period for tone portamentos}
  158.                 Sample : byte;    {current sample}
  159.                 Pan : byte;       {panning}
  160.                 fx,fxdata : byte;
  161.                 fx_sl2,fx_vib : byte;  {slide to & vibrato fx-data}
  162.                 vib_wave : byte;    {vibrato waveform}
  163.                 vib_cnt : byte;     {vibrato counter}
  164.                 trig_cnt : byte;    {retrig counter}
  165.                 arp1,arp2,         {arpeggio params}
  166.                 arp_cnt : byte;     {arpeggio counter}
  167.                 start_fx : byte;    {tick to start do_fx for channel}
  168.                 on : byte;        {0 = channel is muted}
  169.                 bar : byte;       {volume bar}
  170.                 hit : byte;
  171.                 no_fx : byte  {1 = do not get new fx}
  172.               end;
  173.   t_sample = record
  174.                Name : array[1..40] of char;
  175.                Addr : longint;  {address in GUS mem}
  176.                Length : word;
  177.                LoopStart,
  178.                LoopEnd : word;
  179.                ftune : byte;
  180.                Volume : byte;
  181.              end;
  182.   t_note = record
  183.              per : word;
  184.              note,
  185.              sample,
  186.              fx,
  187.              fxdata : byte;
  188.            end;
  189.   t_row = array[0..maxchn-1] of t_note;
  190.   t_pattern = array[0..63] of t_row;
  191.   p_pattern = ^t_pattern;
  192.  
  193.   mod_header = record
  194.                  name : string[20];
  195.                  Length : byte;
  196.                  tag : array[0..3] of char;  {M.K.}
  197.                  chns : byte;  {4..12}
  198.                  samples : byte; {15 / 31}
  199.                end;
  200.  
  201. var
  202.   gus_addr : array[0..32] of longint;
  203.   periods : array[0..1100] of word;
  204.   channels : array[0..maxchn-1] of t_channel;
  205.   samples : array[0..32] of t_sample;
  206.   patterns : array[0..128] of p_pattern;
  207.   orders : array[0..255] of byte;   {order list}
  208.   max_ptn : word;                 {# patterns in mod}
  209.   cur_ptn,cur_row,cur_tick : byte;
  210.   new_ptn,new_row,jump : byte;   {used in jumps}
  211.   speed,nspeed,tempo : byte;
  212.   vblank : boolean;               {true = do not use bpm tempos}
  213.  
  214.   header : mod_header;
  215.   top_addr : longint;         {Next free address in GUS mem}
  216.  
  217.   time_counter : longint;      {For syncing with demos. Increments
  218.                                 every 1/18.2 seconds}
  219.   time_counter2 : longint;    {Increments every tick}
  220.   vrt_flag : byte;   {if 1 then vertical retrace happened}
  221.  
  222. Procedure GUSDelay;
  223. Function VoicePos( V : Byte) : Longint;
  224. Function  GUSPeek(Loc : Longint) : Byte;
  225. Procedure GUSPoke(Loc : Longint; B : Byte);
  226. Function GUSProbe(adr : word) : Boolean;
  227. Procedure GUSFind;
  228. Function  GUSFindMem : Longint;
  229. Procedure GUSSetFreq( V : Byte; hz : Word);
  230. Procedure GUSVoiceControl( V, B : Byte);
  231. Procedure GUSSetBalance( V, Bal : Byte);
  232. Procedure GUSSetVolume( V : Byte; Vol : Word);
  233. Procedure GUSSetLoopMode( V : Byte);
  234. Procedure GUSStopVoice( V : Byte);
  235. Procedure GUSPlayVoice( V, Mode : Byte;VBegin, VStart, VEnd : Longint);
  236. procedure gusrelvoice(v : byte);
  237. procedure GusSetOfs(v : byte;vbegin : longint);
  238. Procedure GUSReset;
  239. procedure gusdeinit;
  240.  
  241. procedure updatenotes;
  242. procedure start_playing;
  243. procedure stop_playing;
  244. procedure set_timer(ticks : word);
  245. procedure init_mod;
  246. procedure free_mod;
  247. procedure load_mod(s : string;debug : boolean);
  248.  
  249.  
  250. implementation
  251.  
  252. var
  253.   oldint : procedure;
  254.   int_tick,o_int_tick : word;
  255.   int_rate : word;
  256.  
  257.   gus_bank : longint;
  258.  
  259.   misc_buf : array[0..5000] of byte;    {buffer used while loading mod}
  260.   misc_buf2 : ^t_memarray;      {points to misc_buf}
  261.  
  262. {$i gus.inc}
  263.  
  264. {$s-}
  265. procedure get_notes;
  266. var
  267.   chn : byte;
  268.   ptn : byte;
  269.   org_sam,sam,note : byte;
  270.   st_ofs : longint;
  271.   per,dper,vol,freq : word;
  272.   _fx,_fxdata : byte;
  273.   mute: byte;
  274.   _ptn : p_pattern;
  275.  
  276. procedure prefx;
  277. var
  278. w : word;
  279. _efxdata : byte;
  280. begin
  281.   case _fx of
  282.     9 : begin
  283.           w := _fxdata*$100;
  284.           st_ofs := w;
  285.           channels[chn].no_fx := 1;
  286.           channels[chn].fx := _fx;
  287.           channels[chn].fxdata := _fxdata;
  288.         end;
  289.     $c : begin
  290.            if _fxdata > 64 then _fxdata := 64;
  291.            vol := _fxdata;
  292.          end;
  293.     $e : begin
  294.            _efxdata := _fxdata and 15;
  295.            case _fxdata shr 4 of
  296.            4 : begin
  297.                  channels[chn].fx := _fx;
  298.                  channels[chn].fxdata := _fxdata;
  299.                  if _efxdata and 3 < 3 then channels[chn].vib_wave := _efxdata
  300.                  else channels[chn].vib_wave := 0 or (_efxdata and 4);
  301.                end;
  302.                $c : if _efxdata and 15 = 0 then begin
  303.                  mute := 1;
  304.                  gusstopvoice(chn+1);
  305.                end;
  306.                $d : if _efxdata > 0 then mute := 2
  307.                     else mute := 0;
  308.            end;
  309.     end;
  310.   end;
  311. end;
  312.  
  313. begin
  314.   ptn := orders[cur_ptn];
  315.   for chn := 0 to header.chns-1 do begin
  316.     if channels[chn].fx = 0 then begin
  317.       sam := channels[chn].sample;
  318.       per := per_table[samples[sam].ftune,
  319.                        channels[chn].note];
  320.       gussetfreq(chn+1,periods[per]);
  321.     end;
  322.     channels[chn].hit := 0;
  323.     if ((patterns[ptn]^[cur_row,chn].per > 0) or
  324.     (patterns[ptn]^[cur_row,chn].sample > 0)) then begin
  325.       mute := 1;
  326.       vol := channels[chn].vol;
  327.       per := channels[chn].per;
  328.       note := channels[chn].note;
  329.       freq := periods[channels[chn].per];
  330.       _fx := patterns[ptn]^[cur_row,chn].fx;
  331.       _fxdata := patterns[ptn]^[cur_row,chn].fxdata;
  332.       org_sam := patterns[ptn]^[cur_row,chn].sample;
  333.       channels[chn].start_fx := 0;
  334.       channels[chn].trig_cnt := 0;
  335.       if org_sam = 0 then begin
  336.         sam := channels[chn].sample;
  337.       end
  338.       else begin
  339.         sam := org_sam;
  340.       end;
  341.       if (_fx = 3) or (_fx = 5) then begin {port to/port to&vol slide}
  342.         mute := 1; {dont restart sample}
  343.         if patterns[ptn]^[cur_row,chn].note > 0 then begin
  344.           note := patterns[ptn]^[cur_row,chn].note;
  345.           dper := per_table[samples[sam].ftune,note];
  346.           if dper > max_per then dper := max_per;
  347.           if dper < min_per then dper := min_per;
  348.           channels[chn].dper := dper;
  349.         end;
  350.       end
  351.       else if patterns[ptn]^[cur_row,chn].per > 0 then begin
  352.         if patterns[ptn]^[cur_row,chn].note > 0 then begin
  353.           note := patterns[ptn]^[cur_row,chn].note;
  354.           per := per_table[samples[sam].ftune,note];
  355.         end
  356.         else if patterns[ptn]^[cur_row,chn].per > 0 then
  357.           per := patterns[ptn]^[cur_row,chn].per;
  358.  
  359.         if per > max_per then per := max_per;
  360.         if per < min_per then per := min_per;
  361.         channels[chn].dper := per;
  362.         channels[chn].per := per;
  363.         freq := periods[per];
  364.         mute := 0;
  365.       end;
  366.       if org_sam > 0 then begin {should I reset volume}
  367.         vol := samples[sam].volume;
  368.         if channels[chn].sample <> org_sam then mute := 0;
  369.       end;
  370.       if samples[sam].length > 0 then st_ofs := 2;
  371.         {coz first 2 bytes = amiga loopinfo, discard them}
  372.       channels[chn].no_fx := 0;
  373.       prefx;
  374.       channels[chn].vol := vol;
  375.       channels[chn].note := note;
  376.       if channels[chn].vib_wave and 4 = 0 then channels[chn].vib_cnt := 0;
  377.       channels[chn].sample := sam;
  378.       channels[chn].bar := channels[chn].vol;
  379.       vol := gusvol[vol]*amp_vol;
  380.       if channels[chn].on = 0 then mute := 1;
  381.       if mute = 0 then begin
  382.         channels[chn].hit := 1;
  383.         gussetbalance(chn+1,channels[chn].pan);
  384.         if (samples[sam].loopend > 2) then
  385.           gusplayall(chn+1,8,gus_addr[sam]+st_ofs,
  386.                                gus_addr[sam]+samples[sam].loopstart,
  387.                                gus_addr[sam]+samples[sam].loopend,freq,vol)
  388.         else gusplayall(chn+1,0,gus_addr[sam]+st_ofs,
  389.                              gus_addr[sam]+st_ofs,
  390.                              gus_addr[sam]+samples[sam].length,freq,vol);
  391.       end
  392.       else if (channels[chn].on = 1) and (mute=1) then gussetvolume(chn+1,vol);
  393.     end;
  394.   end;
  395. end;
  396.  
  397. procedure get_fx;
  398. var
  399. chn,ptn : byte;
  400. _fx,_fxdata : byte;
  401. _efx,_efxdata : byte;
  402. per : word;
  403. b : byte;
  404. w : word;
  405.  
  406. begin
  407.   ptn := orders[cur_ptn];
  408.   new_ptn := cur_ptn;
  409.   new_row := cur_row;
  410.   jump := 0;
  411.   for chn := 0 to header.chns-1 do
  412.   if channels[chn].no_fx = 0 then begin
  413.     channels[chn].start_fx := 0;
  414.     channels[chn].fx := 255;
  415.     _fx := patterns[ptn]^[cur_row,chn].fx;
  416.     _fxdata := patterns[ptn]^[cur_row,chn].fxdata;
  417.     case _fx of
  418.       0 : if _fxdata > 0 then begin {Arpeggio}
  419.             channels[chn].fx := _fx;
  420.             channels[chn].fxdata := _fxdata;
  421.             channels[chn].arp1 := _fxdata shr 4;
  422.             channels[chn].arp2 := _fxdata and 15;
  423.             channels[chn].arp_cnt := 0;
  424.           end;
  425.       1 : begin  {port up}
  426.             channels[chn].fx := _fx;
  427.             channels[chn].fxdata := _fxdata;
  428.             channels[chn].start_fx := 2;
  429.           end;
  430.       2 : begin  {port down}
  431.             channels[chn].fx := _fx;
  432.             channels[chn].fxdata := _fxdata;
  433.             channels[chn].start_fx := 2;
  434.           end;
  435.       3 : begin   {port to}
  436.             channels[chn].fx := _fx;
  437.             if _fxdata > 0 then begin
  438.               channels[chn].fxdata := _fxdata;
  439.               channels[chn].fx_sl2 := _fxdata;
  440.             end
  441.             else channels[chn].fxdata := channels[chn].fx_sl2;
  442.             channels[chn].start_fx := 2;
  443.           end;
  444.       4 : begin    {vibrato}
  445.             channels[chn].fx := _fx;
  446.             b := _fxdata and 15;
  447.             if b = 0 then b := channels[chn].fx_vib and 15;
  448.             w := b;
  449.             b := _fxdata shr 4;
  450.             if b = 0 then b := channels[chn].fx_vib shr 4;
  451.             w := w or (b shl 4);
  452.             b := w;
  453.             channels[chn].fxdata := b;
  454.             channels[chn].fx_vib := b;
  455.           end;
  456.       5 : begin    {port to & vol slide}
  457.              channels[chn].fx := _fx;
  458.              if _fxdata and 15 > 0 then
  459.                _fxdata := _fxdata and 15; {if both ways, then slide down}
  460.              channels[chn].fxdata := _fxdata;
  461.           end;
  462.       6 : begin      {Vibrato & vol slide}
  463.             channels[chn].fx := _fx;
  464.             channels[chn].fxdata := _fxdata;
  465.           end;
  466.       7 : begin      {Tremolo}
  467.             channels[chn].fx := _fx;
  468.             channels[chn].fxdata := _fxdata;
  469.           end;
  470.       8 : begin       {Set panning}
  471.             channels[chn].fx := _fx;
  472.             channels[chn].fxdata := _fxdata;
  473.           end;
  474.       9 : begin   {set sample offset}
  475.             channels[chn].fx := _fx;
  476.             channels[chn].fxdata := _fxdata;
  477.             w := _fxdata * 256;
  478.             b := channels[chn].sample;
  479.             if channels[chn].on = 1 then gussetofs(chn+1,gus_addr[b]+w);
  480.           end;
  481.       $a : begin   {volume slide}
  482.              channels[chn].fx := _fx;
  483.              if _fxdata and 15 > 0 then
  484.                _fxdata := _fxdata and 15; {if both ways, then slide up}
  485.              channels[chn].fxdata := _fxdata;
  486.              channels[chn].start_fx := 2;
  487.            end;
  488.       $b : begin   {position jump}
  489.              if _fxdata < max_ptn then begin
  490.                new_ptn := _fxdata;
  491.                new_row := 0;
  492.                jump := 1;
  493.              end;
  494.            end;
  495.       $c : begin  {Set volume}
  496.              if _fxdata > 64 then _fxdata := 64;
  497.              channels[chn].fx := _fx;
  498.              channels[chn].fxdata := _fxdata;
  499.              channels[chn].vol := _fxdata;
  500.              channels[chn].bar := _fxdata;
  501.              w := gusvol[_fxdata {* main_vol}]*amp_vol;
  502.              if channels[chn].on = 1 then gussetvolume(chn+1,w);
  503.            end;
  504.       $d : begin   {break pattern}
  505.              new_ptn := cur_ptn;
  506.              inc(new_ptn);
  507.              new_row := ((_fxdata and $f0) shr 4)*10+_fxdata and 15;
  508.              jump := 1;
  509.            end;
  510.       $e : begin        {extended effect}
  511.              channels[chn].fx := _fx;
  512.              channels[chn].fxdata := _fxdata;
  513.              _efx := _fxdata shr 4;
  514.              _efxdata := _fxdata and 15;
  515.              case _efx of
  516.                1 : begin
  517.                      per := channels[chn].per;
  518.                      inc(per,_efxdata);
  519.                      if per > max_per then per := max_per;
  520.                      channels[chn].per := per;
  521.                      w := periods[channels[chn].per];
  522.                      gussetfreq(chn+1,w);
  523.                    end;
  524.                2 : begin
  525.                      per := channels[chn].per;
  526.                      dec(per,_efxdata);
  527.                      if per < min_per then per := min_per;
  528.                      channels[chn].per := per;
  529.                      w := periods[channels[chn].per];
  530.                      gussetfreq(chn+1,w);
  531.                    end;
  532.                4 : begin {set vibrato waveform}
  533.                      channels[chn].vib_wave := _efxdata;
  534.                    end;
  535.                5 : begin  {set finetune}
  536.                      samples[channels[chn].sample].ftune := _efxdata;
  537.                    end;
  538.                8 : begin  {set mtm-pan}
  539.                      channels[chn].pan := _efxdata;
  540.                      gussetbalance(chn+1,_efxdata);
  541.                    end;
  542.                9 : if _efxdata > 0 then begin   {retrigger}
  543.                      channels[chn].fx := _fx;
  544.                      channels[chn].fxdata := _fxdata;
  545.                      channels[chn].trig_cnt := _efxdata;
  546.                    end;
  547.                $a : begin   {fine vol slide up}
  548.                       b := channels[chn].vol;
  549.                       inc(b,_efxdata);
  550.                       if b > 64 then b := 64;
  551.                       channels[chn].vol := b;
  552.                       w := gusvol[b{*main_vol}]*amp_vol;
  553.                       if channels[chn].on = 1 then gussetvolume(chn+1,w);
  554.                       channels[chn].bar := b;
  555.                     end;
  556.                $b : begin   {fine vol slide down}
  557.                       b := channels[chn].vol;
  558.                       dec(b,_efxdata);
  559.                       if b > 128 then b := 0;
  560.                       channels[chn].vol := b;
  561.                       w := gusvol[b{*main_vol}]*amp_vol;
  562.                       if channels[chn].on = 1 then gussetvolume(chn+1,w);
  563.                       channels[chn].bar := b;
  564.                     end;
  565.                $c : begin  {cut note}
  566.                       channels[chn].fx := _fx;
  567.                       channels[chn].fxdata := _fxdata;
  568.                     end;
  569.                $d : if _efxdata > 0 then begin
  570.                       channels[chn].fx := _fx;
  571.                       channels[chn].fxdata := _fxdata;
  572.                       channels[chn].start_fx := 1+_efxdata;
  573.                     end
  574.                     else channels[chn].fx := 255;
  575.              end;
  576.            end;
  577.       $f : begin  {set speed}
  578.             channels[chn].fx := _fx;
  579.             channels[chn].fxdata := _fxdata;
  580.              if (_fxdata <= 32) or vblank then begin    {SPEED not tempo}
  581.                nspeed := _fxdata;
  582.                speed := _fxdata;
  583.              end
  584.              else begin
  585.                tempo := _fxdata;
  586.                if tempo < 50 then tempo := 50;
  587.                int_rate := 1193182 div (tempo*4 div 10);
  588.                set_timer(int_rate);
  589.              end;
  590.            end
  591.       else begin
  592.         channels[chn].fx := 255;
  593.         channels[chn].fxdata := 0;
  594.       end;
  595.     end;
  596.   end
  597.   else channels[chn].no_fx := 0;
  598. end;
  599.  
  600. procedure do_fx;
  601. var
  602. chn : byte;
  603. _fx,_fxdata : byte;
  604. _efx,_efxdata : byte;
  605. per : word;
  606. b : byte;
  607. s : shortint;
  608. w : word;
  609.  
  610. begin
  611.   for chn := 0 to header.chns-1 do if channels[chn].on = 1 then begin
  612.     if channels[chn].start_fx > 0 then dec(channels[chn].start_fx);
  613.     _fx := channels[chn].fx;
  614.     _fxdata := channels[chn].fxdata;
  615.     if (channels[chn].on = 1) and (channels[chn].start_fx = 0)
  616.     then case _fx of
  617.       0 : with channels[chn] do begin
  618.             case channels[chn].arp_cnt mod 3 of
  619.               0 : gussetfreq(chn+1,
  620.                     periods[per_table[samples[sample].ftune,note]]);
  621.               1 : gussetfreq(chn+1,
  622.                     periods[per_table[samples[sample].ftune,note+arp1]]);
  623.               2 : gussetfreq(chn+1,
  624.                     periods[per_table[samples[sample].ftune,note+arp2]]);
  625.             end;
  626.             inc(arp_cnt);
  627.           end;
  628.       1 : begin   {port up}
  629.             per := channels[chn].per;
  630.             dec(per,_fxdata);
  631.             if per < min_per then per := min_per;
  632.             channels[chn].per := per;
  633.             gussetfreq(chn+1,periods[per]);
  634.           end;
  635.       2 : begin  {port down}
  636.             per := channels[chn].per;
  637.             inc(per,_fxdata);
  638.             if per > max_per then per := max_per;
  639.             channels[chn].per := per;
  640.             gussetfreq(chn+1,periods[per]);
  641.           end;
  642.       3 : begin   {Port to}
  643.             if channels[chn].per < channels[chn].dper then begin
  644.               w := channels[chn].dper;
  645.               per := channels[chn].per;
  646.               inc(per,channels[chn].fx_sl2);
  647.               if per > w then per := w;
  648.               if per > max_per then per := max_per;
  649.               if per < min_per then per := min_per;
  650.               channels[chn].per := per;
  651.               gussetfreq(chn+1,periods[per]);
  652.             end
  653.             else begin
  654.               w := channels[chn].dper;
  655.               per := channels[chn].per;
  656.               if per-channels[chn].fx_sl2 > per then per := min_per
  657.               else dec(per,channels[chn].fx_sl2);
  658.               if per < w then per := w;
  659.               if per < min_per then per := min_per;
  660.               if per > max_per then per := max_per;
  661.               channels[chn].per := per;
  662.               gussetfreq(chn+1,periods[per]);
  663.             end;
  664.           end;
  665.       4 : begin
  666.             _fxdata := channels[chn].fx_vib;
  667.             b := _fxdata and 15;
  668.             s := vib_tbl[channels[chn].vib_wave,channels[chn].vib_cnt];
  669.             s := (s * b) div 64;
  670.             w := channels[chn].per+s;
  671.             if w > max_per then w := max_per;
  672.             if w < min_per then w := min_per;
  673.             b := _fxdata shr 4;
  674.             gussetfreq(chn+1,periods[w]);
  675.             inc(channels[chn].vib_cnt,b);
  676.             if channels[chn].vib_cnt > 63 then
  677.               channels[chn].vib_cnt := channels[chn].vib_cnt - 64;
  678.           end;
  679.       5 : begin
  680.             {volume slide}
  681.             if _fxdata and 15 > 0 then begin  {slide down}
  682.               b := channels[chn].vol;
  683.               if b-_fxdata >= 0 then dec(b,_fxdata)
  684.               else b := 0;
  685.               if b > 128 then b := 0;
  686.               channels[chn].vol := b;
  687.               channels[chn].bar := b;
  688.               w := gusvol[b {* main_vol}]*amp_vol;
  689.               gussetvolume(chn+1,w);
  690.             end
  691.             else begin   {slide up}
  692.               b := channels[chn].vol;
  693.               inc(b,_fxdata shr 4);
  694.               if b > 64 then b := 64;
  695.               channels[chn].vol := b;
  696.               channels[chn].bar := b;
  697.               w := gusvol[b {* main_vol}]*amp_vol;
  698.               gussetvolume(chn+1,w);
  699.             end;
  700.             _fxdata := channels[chn].fx_sl2;
  701.             if channels[chn].per < channels[chn].dper then begin {port to}
  702.               w := channels[chn].dper;
  703.               per := channels[chn].per;
  704.               inc(per,_fxdata);
  705.               if per > w then per := w;
  706.               if per > max_per then per := max_per;
  707.               if per < min_per then per := min_per;
  708.               channels[chn].per := per;
  709.               gussetfreq(chn+1,periods[per]);
  710.             end
  711.             else begin
  712.               w := channels[chn].dper;
  713.               per := channels[chn].per;
  714.               if per-_fxdata > per then per := min_per
  715.               else dec(per,_fxdata);
  716.               if per < w then per := w;
  717.               if per < min_per then per := min_per;
  718.               if per > max_per then per := max_per;
  719.               channels[chn].per := per;
  720.               gussetfreq(chn+1,periods[per]);
  721.             end;
  722.           end;
  723.       6 : begin
  724.             begin
  725.               b := channels[chn].fx_vib and 15;
  726.               s := vib_tbl[channels[chn].vib_wave,channels[chn].vib_cnt];
  727.               s := (s * b) div 64;
  728.               w := channels[chn].per+s;
  729.               if w > max_per then w := max_per;
  730.               if w < min_per then w := min_per;
  731.               b := channels[chn].fx_vib shr 4;
  732.               gussetfreq(chn+1,periods[w]);
  733.               inc(channels[chn].vib_cnt,b);
  734.               if channels[chn].vib_cnt > 63 then
  735.                 channels[chn].vib_cnt := channels[chn].vib_cnt - 64;
  736.             end;
  737.             {volume slide}
  738.             if _fxdata and 15 > 0 then begin  {slide down}
  739.               b := channels[chn].vol;
  740.               if b-_fxdata >= 0 then dec(b,_fxdata)
  741.               else b := 0;
  742.               if b > 128 then b := 0;
  743.               channels[chn].vol := b;
  744.               channels[chn].bar := b;
  745.               w := gusvol[b {* main_vol}]*amp_vol;
  746.               gussetvolume(chn+1,w);
  747.             end
  748.             else begin   {slide up}
  749.               b := channels[chn].vol;
  750.               inc(b,_fxdata shr 4);
  751.               if b > 64 then b := 64;
  752.               channels[chn].vol := b;
  753.               channels[chn].bar := b;
  754.               w := gusvol[b {* main_vol}]*amp_vol;
  755.               gussetvolume(chn+1,w);
  756.             end;
  757.           end;
  758.       $a : begin  {volume slide}
  759.              if _fxdata and 15 > 0 then begin  {slide down}
  760.                b := channels[chn].vol;
  761.                if b < (_fxdata and 15) then b := 0
  762.                else dec(b,_fxdata and 15);
  763.                if b > 64 then b := 0;
  764.                channels[chn].vol := b;
  765.                channels[chn].bar := b;
  766.                w := gusvol[b]*amp_vol;
  767.                gussetvolume(chn+1,w);
  768.              end
  769.              else begin   {slide up}
  770.                b := channels[chn].vol;
  771.                inc(b,_fxdata shr 4);
  772.                if b > 64 then b := 64;
  773.                channels[chn].vol := b;
  774.                channels[chn].bar := b;
  775.                w := gusvol[b {* main_vol}]*amp_vol;
  776.                gussetvolume(chn+1,w);
  777.              end;
  778.            end;
  779.       $e : begin
  780.              _efx := _fxdata shr 4;
  781.              _efxdata := _fxdata and 15;
  782.              case _efx of
  783.                9 : begin
  784.                      b := channels[chn].sample;
  785.                      dec(channels[chn].trig_cnt);
  786.                      if channels[chn].trig_cnt = 0 then begin
  787.                        gussetofs(chn+1,gus_addr[b]+2);
  788.                        channels[chn].trig_cnt := _efxdata;
  789.                      end;
  790.                    end;
  791.                $c : if _efxdata = 0 then begin
  792.                       gussetvolume(chn+1,0);
  793.                     end
  794.                     else begin
  795.                       dec(_efxdata);
  796.                       b := _fxdata;
  797.                       b := b and $f0;
  798.                       b := b or _efxdata;
  799.                       channels[chn].fxdata := b;
  800.                     end;
  801.                $d : begin
  802.                       w := channels[chn].sample;
  803.                       if channels[chn].on = 1 then begin
  804.                         channels[chn].hit := 1;
  805.                         gussetbalance(chn+1,channels[chn].pan);
  806.                         if (samples[w].loopend > 2) then
  807.                           gusplayall(chn+1,8,gus_addr[w]+2,
  808.                                gus_addr[w]+samples[w].loopstart,
  809.                                gus_addr[w]+samples[w].loopend,
  810.                                periods[channels[chn].per],
  811.                                gusvol[channels[chn].vol]*amp_vol)
  812.                         else  gusplayall(chn+1,0,gus_addr[w]+2,
  813.                              gus_addr[w],
  814.                              gus_addr[w]+samples[w].length+1,
  815.                              periods[channels[chn].per],
  816.                              gusvol[channels[chn].vol]*amp_vol);
  817.                       end;
  818.                     end;
  819.              end;
  820.            end;
  821.     end;
  822.   end;
  823. end;
  824.  
  825. procedure updatenotes;
  826. var
  827. n : integer;
  828. begin
  829.   if cur_ptn > header.length-1 then new_ptn := 0;
  830.   cur_ptn := new_ptn;
  831.   cur_row := new_row;
  832.   if (cur_tick >= speed) and (speed > 0) then begin
  833.     speed := nspeed;
  834.     cur_tick := 0;
  835.     if jump = 0 then inc(cur_row);
  836.     if cur_row > 63 then begin
  837.       inc(cur_ptn);
  838.       cur_row := 0;
  839.       if cur_ptn > header.length-1 then begin
  840.         new_ptn := 0;
  841.         cur_ptn := 0;
  842.       end;
  843.     end;
  844.   end;
  845.   for n := 0 to maxchn-1 do begin
  846.     if channels[n].bar > 1 then dec(channels[n].bar,2)
  847.     else channels[n].bar := 0;
  848.   end;
  849.   new_ptn := cur_ptn;
  850.   new_row := cur_row;
  851.   if speed > 0 then begin
  852.     inc(cur_tick);
  853.     if cur_tick = 1 then begin
  854.       get_notes;
  855.       if port[$3da] and 8 = 8 then vrt_flag := 1;
  856.       get_fx;
  857.     end;
  858.     if port[$3da] and 8 = 8 then vrt_flag := 1;
  859.     do_fx;
  860.     if port[$3da] and 8 = 8 then vrt_flag := 1;
  861.   end;
  862. end;
  863.  
  864. procedure modint; interrupt;
  865. {This happens bpm*4/10 times per second (50hz if vblank).}
  866. begin
  867.   asm sti end;
  868.   if port[$3da] and 8 = 8 then vrt_flag := 1;
  869.   inc(time_counter2);
  870.   updatenotes;
  871.   o_int_tick := int_tick;
  872.   int_tick := int_tick + int_rate;
  873.   if o_int_tick > int_tick then begin
  874.     inc(time_counter);
  875.     asm
  876.       cli
  877.       pushf
  878.       call oldint
  879.     end;
  880.   end
  881.   else
  882.     asm
  883.       mov  al,20h
  884.       out  20h,al  {send EOI}
  885.     end;
  886. end;
  887.  
  888. {$s+}
  889. procedure load_MOD(s : string;debug : boolean);
  890. var
  891. f : file;
  892.  
  893. procedure set_up_modheader;
  894. var
  895. chn : integer;
  896. begin
  897.   header.samples := 31;
  898.   header.name[0] := #20;
  899.   move(misc_buf[0],header.name[1],20);
  900.   header.tag := '    ';
  901.   move(misc_buf[1080],header.tag,4);
  902.   chn := maxchn;
  903.   if header.tag = 'M.K.' then chn := 4
  904.   else if header.tag = 'M!K!' then chn := 4
  905.   else if header.tag = '6CHN' then chn := 6
  906.   else if header.tag = '8CHN' then chn := 8
  907.   else if header.tag = '12CH' then chn := 12
  908.   else begin
  909.     header.samples := 15;
  910.     chn := 4;
  911.   end;
  912.   if chn > maxchn then begin
  913.     mod_error := 1;
  914.     exit;
  915.   end;
  916.   if header.samples = 15 then begin
  917.     move(misc_buf[472],orders[0],128);
  918.     seek(f,600);
  919.     header.length := misc_buf[470];
  920.     header.chns := 4;
  921.   end else begin
  922.     header.length := misc_buf[950];
  923.     move(misc_buf[952],orders[0],128);
  924.     if debug then writeln('Tag: ',header.tag);
  925.   end;
  926.   header.chns := chn;
  927. end;
  928.  
  929. procedure mod_sample_info;
  930. var
  931. n : integer;
  932. maxi : integer;
  933. begin
  934.   for n := 0 to 31 do begin
  935.     fillchar(samples[n].name,22,0);
  936.     samples[n].length := 0;
  937.     samples[n].ftune := 0;
  938.     samples[n].volume := 0;
  939.     samples[n].loopstart := 0;
  940.     samples[n].loopend := 0;
  941.   end;
  942.   for n := 1 to header.samples do begin
  943.     move(misc_buf[(n-1)*30+20],samples[n].name[1],22);
  944.     samples[n].name[23] := #0;
  945.     samples[n].length := 2*swap(misc_buf2^[(n-1)*15+21]); {n*30+42}
  946.     samples[n].ftune := misc_buf[(n-1)*30+44];
  947.     samples[n].volume := misc_buf[(n-1)*30+45];
  948.     samples[n].loopstart := 2*swap(misc_buf2^[(n-1)*15+23]);  {n*30+46}
  949.     samples[n].loopend := 2*swap(misc_buf2^[(n-1)*15+24]);  {n*30+48}
  950.     if samples[n].loopend < 3 then begin
  951.       samples[n].loopend := 0;
  952.       samples[n].loopstart := 0;
  953.     end;
  954.     inc(samples[n].loopend,samples[n].loopstart);
  955.     if samples[n].loopend > samples[n].length then
  956.       samples[n].loopend := samples[n].length;
  957.   end;
  958. end;
  959.  
  960. procedure read_ptn(n : word);
  961. var
  962. row,note : integer;
  963. w,w2,i : word;
  964. b : byte;
  965. mchn : byte;
  966.  
  967. begin
  968.   mchn := header.chns;
  969.   blockread(f,misc_buf,256*mchn);
  970.   for row := 0 to 63 do
  971.     for note := 0 to mchn-1 do begin
  972.       w := misc_buf2^[row*(2*mchn)+note*2];
  973.       w2 := misc_buf2^[row*(2*mchn)+note*2+1];
  974.       asm
  975.         mov  cx,w
  976.         and  cl,15
  977.         xchg cl,ch
  978.         and  cx,0fffh
  979.         mov  i,cx
  980.       end;
  981.       patterns[n]^[row,note].per := i;
  982.       asm
  983.         mov  al,byte ptr w2
  984.         shr  al,4
  985.         mov  ah,byte ptr w
  986.         and  ah,11110000b
  987.         or   al,ah
  988.         xor  ah,ah
  989.         mov  i,ax
  990.       end;
  991.       patterns[n]^[row][note].sample := i;
  992.       patterns[n]^[row][note].fx := lo(w2) and 15;
  993.       patterns[n]^[row][note].fxdata := hi(w2);
  994.       i := patterns[n]^[row,note].per;
  995.       w := 0;
  996.       b := 0;
  997.       while b = 0 do begin
  998.         inc(w);
  999.         if (w > 48) or (i = per_table[0,w]) then b := 1;
  1000.       end;
  1001.       if w <= 48 then patterns[n]^[row,note].note := w
  1002.       else patterns[n]^[row,note].note := 0;
  1003.     end;
  1004. end;
  1005.  
  1006. procedure load_patterns;
  1007. var
  1008. num_ptn : longint;
  1009. n : word;
  1010. m_ptn : integer;
  1011. begin
  1012.   if debug then write('Loading patterns');
  1013.   num_ptn := 0;
  1014.   for n := 0 to 127 do if orders[n] > num_ptn then begin
  1015.     if orders[n] > 127 then begin
  1016.       mod_error := 2;
  1017.       exit;
  1018.     end else num_ptn := orders[n];
  1019.   end;
  1020.   max_ptn := num_ptn+1;
  1021.   for n := 0 to max_ptn-1 do begin
  1022.     if maxavail < 256*header.chns then begin
  1023.       mod_error := 3;          {if error then release memory allocated}
  1024.       if n >= max_ptn-2 then for n := 0 to max_ptn-2 do dispose(patterns[n]);
  1025.       exit;
  1026.     end;
  1027.     if debug then write('.');
  1028.     new(patterns[n]);
  1029.     read_ptn(n);
  1030.   end;
  1031.   if debug then writeln;
  1032. end;
  1033.  
  1034. procedure load2gus(len : word);
  1035. var
  1036. {n : word;
  1037. addlo,addhi : word;}
  1038. l : longint;
  1039.  
  1040. begin
  1041.   l := top_addr;
  1042.   asm
  1043.     mov  di,len
  1044.     mov  si,offset misc_buf
  1045. @@1:
  1046.     {AddLo := L AND $FFFF;
  1047.     AddHi := longint(L and $ff0000) shr 16;}
  1048.       mov  ax,word ptr l
  1049.       mov  cx,ax      {cx=addlo}
  1050.       mov  ax,word ptr l+2
  1051.       and  ax,0ffh
  1052.       mov  bx,ax   {bx=addhi}
  1053.  
  1054.       mov  dx,command   {Port [command] := $43;}
  1055.       mov  al,43h
  1056.       out  dx,al
  1057.  
  1058.       mov  dx,data_low  {Portw[data_low] := AddLo;}
  1059.       mov  ax,cx
  1060.       out  dx,ax
  1061.  
  1062.       mov  dx,command    {Port [command] := $44;}
  1063.       mov  al,44h
  1064.       out  dx,al
  1065.  
  1066.       mov  dx,data_high
  1067.       mov  ax,bx
  1068.       out  dx,ax        {Port [data_high] := AddHi;}
  1069.  
  1070.       add  word ptr l,1     {inc(l,1);}
  1071.       adc  word ptr l+2,0
  1072.  
  1073.     mov  dx,dram_io      {Port [dram_io] := misc_buf[n];}
  1074.     outsb
  1075.  
  1076.     dec  di
  1077.     jnz  @@1
  1078.   end;
  1079.   inc(top_addr,len);
  1080. end;
  1081.  
  1082. procedure load_sample(num : word);
  1083. const
  1084. block = 4096;
  1085. var
  1086. w : word;
  1087. fl,l : word;
  1088. len : longint;
  1089.  
  1090. begin
  1091.   if debug then write('.');
  1092.   guspoke(top_addr,0);
  1093.   inc(top_addr);
  1094.   guspoke(top_addr,0);
  1095.   inc(top_addr);
  1096.   len := samples[num].length+top_addr;
  1097.   if (len > gus_bank+$40000) and (top_addr < gus_bank+$40000) then begin
  1098.     gus_bank := gus_bank+$40000;
  1099.     top_addr := gus_bank;
  1100.   end;
  1101.  
  1102.   samples[num].addr := top_addr;
  1103.   gus_addr[num] := top_addr;
  1104.   if samples[num].length < 1 then exit;
  1105.   {blockread(f,w,2);}  {read amiga repeat bytes}
  1106.   fl := (samples[num].length) div block;
  1107.   l := (samples[num].length) mod block;
  1108.   if fl > 0 then for w := 1 to fl do begin
  1109.     blockread(f,misc_buf,block);
  1110.     load2gus(block);       {load in 4kb blocks}
  1111.   end;
  1112.   if l > 0 then begin
  1113.     blockread(f,misc_buf,l);
  1114.     load2gus(l);           {load remainder}
  1115.   end;
  1116.   if samples[num].loopend > 2 then begin
  1117.     guspoke(top_addr,guspeek(gus_addr[num]+samples[num].loopstart));
  1118.     guspoke(gus_addr[num]+samples[num].loopend+1,
  1119.             guspeek(gus_addr[num]+samples[num].loopstart));
  1120.     inc(top_addr);
  1121.   end;
  1122. end;
  1123.  
  1124. var
  1125. i : integer;
  1126. l : longint;
  1127.  
  1128. begin
  1129.   gus_bank := 0;
  1130.   assign(f,s);
  1131.   {$i-}
  1132.   reset(f,1);
  1133.   blockread(f,misc_buf,1084);  {read module header}
  1134.   i := ioresult;
  1135.   if i <> 0 then begin
  1136.     mod_error := 2;
  1137.     exit;
  1138.   end;
  1139.   set_up_modheader;
  1140.   if mod_error <> 0 then exit;
  1141.   mod_sample_info;
  1142.   load_patterns;
  1143.   if mod_error <> 0 then exit;
  1144.   if debug then write('Loading samples');
  1145.   for i := 0 to 31 do load_sample(i);
  1146.   if debug then writeln;
  1147.   close(f);
  1148.   {$i+}
  1149. end;
  1150.  
  1151. procedure free_mod;
  1152. var
  1153. n,i : word;
  1154. begin
  1155.   for n := max_ptn-1 downto 0 do dispose(patterns[n]);
  1156.   top_addr := 16;
  1157.   for n := 0 to 31 do with samples[n] do begin
  1158.     addr := 0;
  1159.     for i := 0 to sizeof(name) do name[i] := #0;
  1160.     length := 0;
  1161.     loopstart := 0;
  1162.     loopend := 0;
  1163.     ftune := 0;
  1164.     volume := 0;
  1165.   end;
  1166.   gus_bank := 0;
  1167. end;
  1168.  
  1169. procedure init_mod;
  1170. var
  1171. n,i : integer;
  1172. l : longint;
  1173.  
  1174. begin
  1175.   vrt_flag := 0;
  1176.   misc_buf2 := @misc_buf;
  1177.   for n := 10 to 1050 do begin
  1178.        {gusperiod:=586580935 div (amigaperiod * (divisor div 100 shl 4))}
  1179.        {divisor = 44100}
  1180.     {l := 7093789 div (n*2);
  1181.     l := l div 40;}
  1182.     l := n;
  1183.     l := 586580935 div (l * 7056);
  1184.     periods[n] := l;
  1185.     {hz = 7093789.2/(per*2)}
  1186.   end;
  1187.   for n := 0 to 255 do orders[n] := 0;
  1188.   for n := 0 to maxchn-1 do begin
  1189.     channels[n].vol := 64;
  1190.     channels[n].per := 0;
  1191.     channels[n].dper := 0;
  1192.     channels[n].sample := 0;
  1193.     channels[n].pan := 7;  {middle}
  1194.     channels[n].note := 0;
  1195.   end;
  1196.   for n := 0 to 31 do with samples[n] do begin
  1197.     addr := 0;
  1198.     for i := 0 to sizeof(name) do name[i] := #0;
  1199.     length := 0;
  1200.     loopstart := 0;
  1201.     loopend := 0;
  1202.     ftune := 0;
  1203.     volume := 0;
  1204.   end;
  1205.   for n := 0 to 128 do patterns[n] := nil;
  1206.   for n := 1 to 14 do gussetvolume(n,0);
  1207.   for n := 1 to 14 do gusstopvoice(n);
  1208.   cur_ptn := 0;
  1209.   cur_row := 0;
  1210.   new_ptn := 0;
  1211.   new_row := 0;
  1212.   cur_tick := 0;
  1213.   for n := 0 to 31 do guspoke(n,0);
  1214.   top_addr := 16;
  1215.   gus_bank := 0;
  1216.   vblank := false;
  1217.   getintvec(8,@oldint);
  1218. end;
  1219.  
  1220. procedure set_timer(ticks : word);
  1221. begin
  1222.   asm cli end;
  1223.   port[$43] := $36;
  1224.   port[$40] := lo(ticks);
  1225.   port[$40] := hi(ticks);
  1226.   asm sti end;
  1227. end;
  1228.  
  1229. procedure stop_playing;
  1230. var
  1231. n : integer;
  1232. begin
  1233.   int_rate := 65535;
  1234.   set_timer(65535);
  1235.   setintvec(8,@oldint);
  1236.   for n := 1 to maxchn do GusStopVoice(n);
  1237. end;
  1238.  
  1239. procedure start_playing;
  1240. var
  1241. n : integer;
  1242. begin
  1243.   for n := 0 to maxchn-1 do begin
  1244.     channels[n].vol := 0;
  1245.     channels[n].per := 428;
  1246.     channels[n].sample := 0;
  1247.     channels[n].pan := 7;  {middle}
  1248.     channels[n].on := 1;
  1249.     channels[n].dper := 428;
  1250.     channels[n].bar := 0;
  1251.     channels[n].fx := 255;
  1252.     channels[n].fxdata := 0;
  1253.     channels[n].fx_sl2 := 0;
  1254.     channels[n].fx_vib := 0;
  1255.     channels[n].vib_cnt := 0;
  1256.     channels[n].vib_wave := 0;
  1257.     channels[n].note := 0;
  1258.     channels[n].hit := 0;
  1259.     channels[n].no_fx := 0;
  1260.     channels[n].start_fx := 0;
  1261.     channels[n].arp1 := 0;
  1262.     channels[n].arp2 := 0;
  1263.     channels[n].arp_cnt := 0;
  1264.   end;
  1265.   speed := 6;
  1266.   nspeed := 6;
  1267.   tempo := 125;
  1268.   channels[0].pan := 7-def_pan;
  1269.   channels[1].pan := 7+def_pan;
  1270.   channels[2].pan := 7+def_pan;
  1271.   channels[3].pan := 7-def_pan;
  1272.   if maxchn > 4 then for n := 4 to maxchn-1 do
  1273.     channels[n].pan := channels[n-4].pan;
  1274.   if maxchn > 8 then for n := 8 to maxchn-1 do
  1275.     channels[n].pan := channels[n-8].pan;
  1276.   jump := 0;
  1277.   int_tick := 0;
  1278.   cur_ptn := 0;
  1279.   cur_row := 0;
  1280.   new_ptn := 0;
  1281.   new_row := 0;
  1282.   cur_tick := 0;
  1283.   time_counter := 0;
  1284.   time_counter2 := 0;
  1285.   asm cli end;
  1286.   setintvec(8,@modint);
  1287.   int_rate := 1193182 div 50;
  1288.   set_timer(int_rate);
  1289.   asm sti end;
  1290. end;
  1291.  
  1292. begin
  1293. end.
  1294.